// FacebookService.cs
// Facebook/Framework/Service
// Copyright (c) 2007, Nikhil Kothari. All Rights Reserved.
//

using System;
using System.Diagnostics;
using Facebook.Service.Core;

namespace Facebook.Service {

    /// <summary>
    /// This class provides access to the APIs exposed by the Facebook service.
    /// </summary>
    public sealed class FacebookService {

        private const string FacebookUrl = "http://www.facebook.com";
        private const string FacebookProfileUrl = "http://www.facebook.com/profile.php?id={0}";

        private FacebookSession _session;

        private FeedService _feedService;
        private FqlService _fqlService;
        private FbmlService _fbmlService;
        private FriendsService _friendsService;
        private ProfileService _profileService;
        private UsersService _userService;
        private NotificationsService _notificationsService;
        private EventsService _eventsService;
        private GroupsService _groupsService;
        private PhotosService _photosService;
        private PermissionsService _permissionsService;
        private PreferencesService _preferencesService;
        private PagesService _pagesService;

        /// <summary>
        /// Initializes an instance of a FacebookService with the specified
        /// session.
        /// </summary>
        /// <param name="session">The session associated with requests issued to the service.</param>
        public FacebookService(FacebookSession session) {
            if (session == null) {
                throw new ArgumentNullException("session");
            }

            _session = session;
        }

        /// <summary>
        /// Creates an instance of a FacebookService with the specified application
        /// and infinite session information.
        /// </summary>
        /// <param name="appKey">The application key used as an API key.</param>
        /// <param name="secret">The application secret used to sign requests.</param>
        /// <param name="sessionKey">The previously saved infinite session key.</param>
        /// <param name="userID">The user ID associated with the saved session key. This is the page ID if the session represents a page.</param>
        /// <param name="pageUserID">The user ID of the user browsing the page if the session is associated with a page.</param>
        public FacebookService(string appKey, string secret, string sessionKey, string userID, string pageUserID)
            : this(new FacebookInfiniteSession(appKey, secret, sessionKey, userID, pageUserID)) {
        }

        /// <summary>
        /// Gets the service APIs that allow accessing event information.
        /// </summary>
        public EventsService Events {
            get {
                if (_eventsService == null) {
                    _eventsService = new EventsService(_session);
                }
                return _eventsService;
            }
        }

        /// <summary>
        /// Gets the service APIs related to working against FBML.
        /// </summary>
        public FbmlService Fbml {
            get {
                if (_fbmlService == null) {
                    _fbmlService = new FbmlService(_session);
                }
                return _fbmlService;
            }
        }

        /// <summary>
        /// Gets the service APIs related to the user's feeds on Facebook.
        /// </summary>
        public FeedService Feed {
            get {
                if (_feedService == null) {
                    _feedService = new FeedService(_session);
                }
                return _feedService;
            }
        }

        /// <summary>
        /// Gets the service APIs that allow executing FQL-based queries.
        /// </summary>
        public FqlService Fql {
            get {
                if (_fqlService == null) {
                    _fqlService = new FqlService(_session);
                }
                return _fqlService;
            }
        }

        /// <summary>
        /// Gets the service APIs related to the user's friends on Facebook.
        /// </summary>
        public FriendsService Friends {
            get {
                if (_friendsService == null) {
                    _friendsService = new FriendsService(_session);
                }
                return _friendsService;
            }
        }

        /// <summary>
        /// Gets the service APIs that allow accessing group information.
        /// </summary>
        public GroupsService Groups {
            get {
                if (_groupsService == null) {
                    _groupsService = new GroupsService(_session);
                }
                return _groupsService;
            }
        }

        /// <summary>
        /// Gets the service APIs that allow accessing and sending notifications.
        /// </summary>
        public NotificationsService Notifications {
            get {
                if (_notificationsService == null) {
                    _notificationsService = new NotificationsService(_session);
                }
                return _notificationsService;
            }
        }

        /// <summary>
        /// Gets the service APIs that allow accessing information about Facebook pages.
        /// </summary>
        public PagesService Pages {
            get {
                if (_pagesService == null) {
                    _pagesService = new PagesService(_session);
                }
                return _pagesService;
            }
        }

        /// <summary>
        /// Gets the user ID of the user using an application within the context of a
        /// Facebook page.
        /// </summary>
        public string PageUserID {
            get {
                return _session.PageUserID;
            }
        }

        /// <summary>
        /// Gets the service APIs that allows determining whether specific permissions have
        /// been granted.
        /// </summary>
        public PermissionsService Permissions {
            get {
                if (_permissionsService == null) {
                    _permissionsService = new PermissionsService(_session);
                }
                return _permissionsService;
            }
        }

        /// <summary>
        /// Gets the service APIs that allow accessing photo information.
        /// </summary>
        public PhotosService Photos {
            get {
                if (_photosService == null) {
                    _photosService = new PhotosService(_session);
                }
                return _photosService;
            }
        }

        /// <summary>
        /// Gets the service APIs related to the user's preferences for the application.
        /// </summary>
        public PreferencesService Preferences {
            get {
                if (_preferencesService == null) {
                    _preferencesService = new PreferencesService(_session);
                }
                return _preferencesService;
            }
        }

        /// <summary>
        /// Gets the service APIs related to the user's profile page on Facebook.
        /// </summary>
        public ProfileService Profile {
            get {
                if (_profileService == null) {
                    _profileService = new ProfileService(_session);
                }
                return _profileService;
            }
        }

        /// <summary>
        /// Gets the URL of the user's profile on Facebook. If this session
        /// is associated with a page, the page's URL is returned.
        /// </summary>
        public string ProfileUrl {
            get {
                string userID = _session.UserID;
                if (String.IsNullOrEmpty(userID) == false) {
                    return String.Format(FacebookProfileUrl, userID);
                }
                return FacebookUrl;
            }
        }

        /// <summary>
        /// The current Facebook session associated with this service.
        /// </summary>
        public FacebookSession Session {
            get {
                return _session;
            }
        }

        /// <summary>
        /// Gets the URL of the user's profile on Facebook.
        /// </summary>
        [Obsolete("Use the ProfileUrl property instead.")]
        public string UserProfileUrl {
            get {
                string userID = _session.UserID;
                if (String.IsNullOrEmpty(userID) == false) {
                    return String.Format(FacebookProfileUrl, userID);
                }
                return FacebookUrl;
            }
        }

        /// <summary>
        /// Gets the ID of the user associated with the current session.
        /// </summary>
        public string UserID {
            get {
                return _session.UserID;
            }
        }

        /// <summary>
        /// Gets the service APIs that allow access to information on Facebook users.
        /// </summary>
        public UsersService Users {
            get {
                if (_userService == null) {
                    _userService = new UsersService(_session);
                }
                return _userService;
            }
        }
    }
}
